﻿using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Domain;
using Nop.Core.Domain.Orders;
using Nop.Plugin.Widgets.EKomi.Models;
using Nop.Services.Catalog;
using Nop.Services.Configuration;
using Nop.Services.Logging;
using Nop.Services.Orders;
using Nop.Web.Framework.Controllers;
using Nop.Services.Customers;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Payments;
using Nop.Services.Messages;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Messages;
using Nop.Core.Infrastructure;
using Nop.Services.Localization;
using Nop.Web.Framework.Security;
using Nop.Services.Security;
using Nop.Services.Authentication;
using Nop.Core.Domain.Security;
using System.Security;
using Nop.Services.Stores;
using System.Collections.Generic;
using Nop.Core.Caching;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using Nop.Plugin.Widgets.EKomi.Services;

namespace Nop.Plugin.Widgets.EKomi.Controllers
{
    public class EKomiController : BasePluginController
    {

        internal const string FEEDBACK_ALL_KEY = "Nop.eKomi.feedback";
        internal const string FEEDBACK_FILTER_KEY = "Nop.eKomi.filteredfeedback";


        private readonly IWorkContext _workContext;
        private readonly IStoreContext _storeContext;
        private readonly IStoreService _storeService;
        private readonly IWebHelper _webHelper;
        private readonly ISettingService _settingService;
        private readonly IOrderService _orderService;
        private readonly ILogger _logger;
        private readonly ICategoryService _categoryService;
        private readonly IProductAttributeParser _productAttributeParser;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly IEmailAccountService _emailAccountService;
        private readonly EmailAccountSettings _emailAccountSettings;
        private readonly LocalizationSettings _localizationSettings;
        private readonly IGiftCardService _giftCardService;
        private readonly IWorkflowMessageService _workflowMessageService;
        private readonly ILocalizationService _localizationService;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly IPermissionService _permissionService;
        private readonly IEncryptionService _encryptionService;
        private readonly ICustomerService _customerService;
        private readonly CustomerSettings _customerSettings;
        private readonly IAuthenticationService _authenticationService;
        private readonly ICacheManager _cacheManager;
        private readonly Regex _regex;

        public EKomiController(IWorkContext workContext,
           IStoreContext storeContext, IStoreService storeService,
            IWebHelper webHelper, 
            ISettingService settingService,
            IOrderService orderService, ILogger logger,
            ICategoryService categoryService, IProductAttributeParser productAttributeParser,
            StoreInformationSettings storeInformationSettings,
            IEmailAccountService emailAccountService,
            EmailAccountSettings emailAccountSettings,
            LocalizationSettings localizationSettings,
            IGiftCardService giftCardService,
            IWorkflowMessageService workflowMessageService,
            ILocalizationService localizationService,
            ICustomerActivityService customerActivityService,
            IPermissionService permissionService,
            IEncryptionService encryptionService,
            ICustomerService customerService,
            CustomerSettings customerSettings,
            IAuthenticationService authenticationService,
            ICacheManager cacheManager)
        {
            this._workContext = workContext;
            this._storeContext = storeContext;
            this._storeService = storeService;
            this._webHelper = webHelper;
            this._settingService = settingService;
            this._orderService = orderService;
            this._logger = logger;
            this._categoryService = categoryService;
            this._productAttributeParser = productAttributeParser;
            this._storeInformationSettings = storeInformationSettings;
            this._emailAccountService = emailAccountService;
            this._emailAccountSettings = emailAccountSettings;
            this._localizationSettings = localizationSettings;
            this._giftCardService = giftCardService;
            this._workflowMessageService = workflowMessageService;
            this._localizationService = localizationService;
            this._customerActivityService = customerActivityService;
            this._permissionService = permissionService;
            this._encryptionService = encryptionService;
            this._customerService = customerService;
            this._customerSettings = customerSettings;
            this._authenticationService = authenticationService;
            this._cacheManager = EngineContext.Current.ContainerManager.Resolve<ICacheManager>("nop_cache_static");

            System.Text.RegularExpressions.RegexOptions options = ((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Multiline)
    | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            _regex = new Regex("(?:^|,)(\\\"(?:[^\\\"]+|\\\"\\\")*\\\"|[^,]*)", options);

        }

        [AdminAuthorize]
        [ChildActionOnly]
        public ActionResult Configure()
        {
            //load settings for a chosen store scope
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
            var spreadButtonSettings = _settingService.LoadSetting<EKomiSettings>(storeScope);
            var model = new ConfigurationModel();
            model.InterfaceId = spreadButtonSettings.InterfaceId;
            model.InterfacePassword = spreadButtonSettings.InterfacePassword;
            model.NoFeedbackForTheseSku = spreadButtonSettings.NoFeedbackForTheseSku;

            model.WidgetScript   = spreadButtonSettings.WidgetScript;
            model.DisplayRating  = spreadButtonSettings.DisplayRating;
            model.DisplayStars   = spreadButtonSettings.DisplayStars;
            model.CommentsNumber = spreadButtonSettings.CommentsNumber ;

            model.SendMailToEKomi = spreadButtonSettings.SendMailToEKomi;
            model.Email = spreadButtonSettings.Email;
            model.Subject = spreadButtonSettings.Subject;
            model.Body = spreadButtonSettings.Body;

            model.ActiveStoreScopeConfiguration = storeScope;
            if (storeScope > 0)
            {
                model.InterfaceId_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.InterfaceId, storeScope);
                model.InterfacePassword_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.InterfacePassword, storeScope);
                model.NoFeedbackForTheseSku_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.NoFeedbackForTheseSku, storeScope);

                model.WidgetScript_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.WidgetScript   , storeScope);
                model.DisplayRating_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.DisplayRating  , storeScope);
                model.DisplayStars_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.DisplayStars   , storeScope);
                model.CommentsNumber_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.CommentsNumber , storeScope);

                model.SendMailToEKomi_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.SendMailToEKomi, storeScope);
                model.Email_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.Email, storeScope);
                model.Subject_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.Subject, storeScope);
                model.Body_OverrideForStore = _settingService.SettingExists(spreadButtonSettings, x => x.Body, storeScope);
            }

            return View("Nop.Plugin.Widgets.EKomi.Views.EKomi.Configure", model);
        }

        [HttpPost]
        [AdminAuthorize]
        [ChildActionOnly]
        public ActionResult Configure(ConfigurationModel model)
        {
            if (!ModelState.IsValid)
                return Configure();

            //load settings for a chosen store scope
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
            var spreadButtonSettings = _settingService.LoadSetting<EKomiSettings>(storeScope);
            spreadButtonSettings.InterfaceId = model.InterfaceId;
            spreadButtonSettings.InterfacePassword = model.InterfacePassword;
            spreadButtonSettings.NoFeedbackForTheseSku = model.NoFeedbackForTheseSku;

            spreadButtonSettings.WidgetScript = model.WidgetScript;
            spreadButtonSettings.DisplayRating = model.DisplayRating;
            spreadButtonSettings.DisplayStars = model.DisplayStars;
            spreadButtonSettings.CommentsNumber  = model.CommentsNumber;

            spreadButtonSettings.SendMailToEKomi = model.SendMailToEKomi;
            spreadButtonSettings.Email = model.Email;
            spreadButtonSettings.Subject = model.Subject;
            spreadButtonSettings.Body = model.Body;

            /* We do not clear cache after each setting update.
             * This behavior can increase performance because cached settings will not be cleared 
             * and loaded from database after each update */
            if (model.InterfaceId_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.InterfaceId, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.InterfaceId, storeScope);

            if (model.InterfacePassword_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.InterfacePassword, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.InterfacePassword, storeScope);

            if (model.NoFeedbackForTheseSku_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.NoFeedbackForTheseSku, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.NoFeedbackForTheseSku, storeScope);

            if (model.WidgetScript_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.WidgetScript, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.WidgetScript, storeScope);

            if (model.DisplayRating_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.DisplayRating, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.DisplayRating, storeScope);

            if (model.DisplayStars_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.DisplayStars, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.DisplayStars, storeScope);

            if (model.CommentsNumber_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.CommentsNumber, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.CommentsNumber, storeScope);


            if (model.SendMailToEKomi_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.SendMailToEKomi, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.SendMailToEKomi, storeScope);

            if (model.Email_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.Email, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.Email, storeScope);

            if (model.Subject_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.Subject, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.Subject, storeScope);

            if (model.Body_OverrideForStore || storeScope == 0)
                _settingService.SaveSetting(spreadButtonSettings, x => x.Body, storeScope, false);
            else if (storeScope > 0)
                _settingService.DeleteSetting(spreadButtonSettings, x => x.Body, storeScope);



            //now clear settings cache
            _settingService.ClearCache();

            return Configure();
        }

        [ChildActionOnly]
        public ActionResult Script()
        {
            //load settings for a chosen store scope
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
            var spreadButtonSettings = _settingService.LoadSetting<EKomiSettings>(storeScope);

            var model = new ScriptModel();
            model.WidgetScript = spreadButtonSettings.WidgetScript;

            return View("Nop.Plugin.Widgets.EKomi.Views.EKomi.Script", model);
        }



        public ActionResult Feedback()
        {
            //load settings for a chosen store scope
            var storeScope = this.GetActiveStoreScopeConfiguration(_storeService, _workContext);
            var spreadButtonSettings = _settingService.LoadSetting<EKomiSettings>(storeScope);
            var _eKomiService = EngineContext.Current.Resolve<IEKomiService>();

            var model = new FeedbackModel();


            model.DisplayRating = spreadButtonSettings.DisplayRating;
            model.DisplayStars = spreadButtonSettings.DisplayStars;
            model.Feedback = _eKomiService.GetRandom(spreadButtonSettings.CommentsNumber, 5, 30)
                .Select(x =>
                {
                    var subCatModel = new Feedback()
                    {
                        Comment = Nop.Core.Html.HtmlHelper.ConvertPlainTextToHtml(x.Comment),
                        Rating = x.Rating
                    };
                    return subCatModel;
                })
                .ToArray();

            //http://www.santiane.fr/santiane-avis.htm



            return View("Nop.Plugin.Widgets.EKomi.Views.EKomi.Feedback", model);
        }









    }
}